package cn.hzu580.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;

import com.opensymphony.xwork2.ActionContext;

import cn.hzu580.bean.NoticeSender;
import cn.hzu580.constant.Hzu580Config;
import cn.hzu580.constant.MissionState;
import cn.hzu580.dao.BaseDAO;
import cn.hzu580.entity.Message;
import cn.hzu580.entity.Mission;
import cn.hzu580.entity.User;
import cn.hzu580.service.MessageService;
import cn.hzu580.service.MissionService;
import cn.hzu580.util.DateUtil;
import cn.hzu580.util.MissionComparartor;
import cn.hzu580.util.MsgCodeUtil;
import cn.hzu580.vo.MessageVO;
import cn.hzu580.vo.MissionVO;

@Service("mission")
public class MissonServiceImpl implements MissionService	 {

	@Resource(name="DAO")
	private BaseDAO baseDAO;
	
	@Resource
	private NoticeSender sender;
	
	@Resource(name="message")
	private MessageService messageService;
	
	
	private boolean updateScore(User pUser, int score , boolean ignoreNegative) {
		User user = (User) baseDAO.get(User.class, pUser.getUid());
		//如果为负数
		if(user.getScore() + score < 0 && !ignoreNegative){
			return false;
		}
		user.setScore(user.getScore() + score);
		baseDAO.update(user);
		return true;
	}

	
	
	@Override
	public void create(MissionVO vo) {
		Map session = ActionContext.getContext().getSession();
		User user = (User) baseDAO.get(User.class, (Serializable) session.get("uid"));
		if(updateScore(user, - vo.getReward(), false)){
			//赋值
			Mission mission = new Mission();
			mission.setCreate_time(DateUtil.now());
			mission.setOwner(user);
			mission.setSummary(vo.getSummary());
			mission.setDescription(vo.getDescription());
			mission.setType(vo.getType());
			mission.setIs_show_tel(vo.isIs_show_tel());
			mission.setSex_limit(vo.getSex_limit());
			mission.setIs_fast_mode(vo.isIs_fast_mode());
			mission.setIs_safe_mode(vo.isIs_safe_mode());
			mission.setBuilding(vo.getBuilding());
			mission.setReward(vo.getReward());
			mission.setRoom(vo.getRoom());
			baseDAO.insert(mission);
		}else{
			throw new RuntimeException("score is not enough");
		}
	}
	
	@Override
	public Mission get(MissionVO vo) {
		return (Mission) baseDAO.get(Mission.class, vo.getId());
	}

	@Override
	public List<Mission> listMain(MissionVO vo) {
		Criteria qbc = baseDAO.createQBC(Mission.class);
		//只显示未进行的任务
		qbc.add(Restrictions.eq("state",MissionState.NOT_START));
		//请求条件
		if(vo.getFast_mode_limit() != 2){
			qbc.add(Restrictions.eq("is_fast_mode",vo.getFast_mode_limit() == 1 ? true : false));
		}
		if(vo.getSex_limit() != 2){
			qbc.add(Restrictions.eq("sex_limit",vo.getSex_limit()));
		}
		if(vo.getReward() != 0){
			qbc.add(Restrictions.ge("reward", vo.getReward()));
		}
		if(vo.getTime_ago() != 0){
			Date date = DateUtil.now();
			date.setHours(date.getHours() - vo.getTime_ago());
			qbc.add(Restrictions.ge("create_time", date));
		}
		if(vo.getBuilding() != null && !vo.getBuilding().equals("")){
			qbc.add(Restrictions.eq("building", vo.getBuilding()));
		}
		List<Mission> list = (List<Mission>) qbc.list();
		
		//排序
		list.sort(new MissionComparartor());
		
		//确定返回范围
		int first = 0;
		for (int i = 0; i < list.size(); i++) {
			if(list.get(i).getId() == vo.getNext_id()){
				first = i+1;
				break;
			}
		}
		if(first >= list.size()){
			return new ArrayList<>();
		}
		int to = first + Hzu580Config.RESULT_NUM ;
		if(to > list.size()){
			to = list.size();
		}
		
		//截取范围生成子列表返回
		return list.subList(first, to);
	}

	
	@Override
	public List<Mission> listMine() {
		User user = (User) baseDAO.get(User.class, (Serializable) ActionContext.getContext().getSession().get("uid"));
		Map<String, Object> parameters = new HashMap<String , Object>();
		parameters.put("uid", user.getUid());
		List<Mission> list = (List<Mission>) baseDAO.exeQuery("from Mission where owner.uid=:uid and state!=3 and state!=-2", parameters);
		return list;
	}
	
	
	@Override
	public void cancel(MissionVO vo) {
		Mission mission = (Mission) baseDAO.get(Mission.class, vo.getId());
		User user = (User) baseDAO.get(User.class, (Serializable) ActionContext.getContext().getSession().get("uid"));
		//检查任务状态
		if(mission.getState() == MissionState.STARTED){
			if(user.getUid().equals(mission.getOwner().getUid())){
				sender.send(mission.getOwner().getName()+"取消了任务", mission.getHelper(), mission);
			}else if(user.getUid().equals(mission.getHelper().getUid())){
				sender.send(mission.getHelper().getName()+"放弃了任务", mission.getOwner(), mission);
				updateScore(mission.getOwner(), mission.getReward() , true);
				updateScore(mission.getHelper(), - mission.getReward() , true);
			}else{
				throw new RuntimeException("only owner and helper can cancel mission");
			}
		}else if(mission.getState() == MissionState.NOT_START){
			if(!user.getUid().equals(mission.getOwner().getUid())){
				throw new RuntimeException("mission's owner is not you");
			}
			updateScore(mission.getOwner(), mission.getReward(), true);
		}else{
			throw new RuntimeException("the mission can not be cancel now");
		}
		mission.setState(MissionState.CANCELED);
		baseDAO.update(mission);
	}

	@Override
	public void start(MissionVO vo) {
		Mission mission = (Mission) baseDAO.get(Mission.class, vo.getId());
		//检查任务状态
		if(mission.getState() != MissionState.NOT_START){
			throw new RuntimeException("mission has been started");
		}
		//赋值
		mission.setState(MissionState.STARTED);
		mission.setStart_time(DateUtil.now());
		//判断是否快速模式
		if(mission.isIs_fast_mode()){
			User helper = (User) baseDAO.get(User.class, (Serializable) ActionContext.getContext().getSession().get("uid"));
			//判断发起者
			if(ActionContext.getContext().getSession().get("uid").equals(mission.getOwner().getUid())){
				throw new RuntimeException("you can not start mission by yourself on fast mode");
			}
			//判断是否安全模式
			if(!helper.isIs_approve() && mission.isIs_safe_mode()){
				throw new RuntimeException("you need real name authentication before start this mission");
			}
			sender.send(helper.getName()+"接受了你的任务并开始进行了", mission.getOwner(),mission);
			MsgCodeUtil.sendNoticeOwnerMsg(helper.getName(), mission.getSummary(), mission.getOwner().getTel());
			mission.setHelper(helper);
		}else{
			//判断发起者
			if(!ActionContext.getContext().getSession().get("uid").equals(mission.getOwner().getUid())){
				throw new RuntimeException("mission's owner is not you");
			}
			//判断帮助者是否在留言列表中
			MessageVO messageVO = new MessageVO();
			messageVO.setMission(vo);
			User helper = (User) baseDAO.get(User.class, vo.getHelper().getUid());
			List<Message> list = messageService.getAll(messageVO);
			for (Message message : list) {
				if(message.getOwner().getUid().equals(helper.getUid())){
					//防止自己接自己任务
					if(message.getOwner().getUid().equals(mission.getOwner().getUid())){
						throw new RuntimeException("you can not start mission which you created");
					}
					//判断是否安全模式
					if(!helper.isIs_approve() && mission.isIs_safe_mode()){
						throw new RuntimeException("the helper hasn't done real name authentication");
					}
					sender.send(mission.getOwner().getName()+"决定让你帮助TA，快开始吧", helper, mission);
					MsgCodeUtil.sendNoticeHelperMsg(mission.getOwner().getName(), mission.getSummary(), helper.getTel());
					//更新
					mission.setHelper(helper);
					baseDAO.update(mission);
					return;
				}
			}
			throw new RuntimeException("helper is not in the list of message for this mission");
		}	

	}

	@Override
	public void finish(MissionVO vo) {
		Mission mission = (Mission) baseDAO.get(Mission.class, vo.getId());
		//判断所有者
		if(!ActionContext.getContext().getSession().get("uid").equals(mission.getOwner().getUid())){
			throw new RuntimeException("mission's owner is not you");
		}
		//更新任务状态
		if(mission.getState() != MissionState.STARTED){
			throw new RuntimeException("it must be started before finished");
		}
		//检查评价是否合法
		if(vo.getEvaluate() <1.0 || vo.getEvaluate() > 5.0){
			throw new RuntimeException("evaluate is illegal, it must be great than 1.0 and less than 5.0");
		}
		mission.setEvaluate(vo.getEvaluate());
		mission.setState(MissionState.FINISHED);
		mission.setFinish_time(DateUtil.now());
		baseDAO.update(mission);
		//更新积分
		updateScore(mission.getHelper(), mission.getReward(), true); 
		//更新评价
		Map<String, Object> parameters = new HashMap<String , Object>();
		parameters.put("helper_uid", mission.getHelper().getUid());
		parameters.put("finished", MissionState.FINISHED);
		int sum = baseDAO.exeQuery("from Mission where helper.uid=:helper_uid and state>=:finished", parameters).size();
		float evaluate = (mission.getEvaluate() + mission.getHelper().getEvaluate() * (sum-1) ) / sum;
		User user = (User) baseDAO.get(User.class, mission.getHelper().getUid());
		user.setEvaluate(evaluate);
		//更新经验值：评价取整数+悬赏分=经验值获取
		user.setExperience(user.getExperience() + mission.getReward() + (int)vo.getEvaluate());
		baseDAO.update(user);
	}

	@Override
	public void delete(MissionVO vo) {
		Mission mission = (Mission) baseDAO.get(Mission.class, vo.getId());
		//判断所有者
		if(!ActionContext.getContext().getSession().get("uid").equals(mission.getOwner().getUid())){
			throw new RuntimeException("mission's owner is not you");
		}
		//更新任务状态
		if(mission.getState() == MissionState.CANCELED){
			mission.setState(MissionState.DELETED_AFTER_CANCELED);
		}else if(mission.getState() == MissionState.FINISHED){
			mission.setState(MissionState.DELETED_AFTER_FINISHED);
		}else{
			throw new RuntimeException("it must be finished or canceled before delete");
		}
		baseDAO.update(mission);
	}

	@Override
	public Map<String, Object> count(MissionVO vo) {
		Map<String, Object> parameters = new HashMap<String , Object>();
		parameters.put("uid", vo.getUid());
		parameters.put("finished", MissionState.FINISHED);
		int owner = baseDAO.exeQuery("from Mission where owner.uid=:uid and state=:finished", parameters).size();
		int helper = baseDAO.exeQuery("from Mission where helper.uid=:uid and state=:finished", parameters).size();
		Map<String, Object> result = new HashMap<String , Object>();
		result.put("owner", owner);
		result.put("helper", helper);
		return result;
		
	}

	@Override
	public List<Mission> listHelp(MissionVO vo) {
		Map<String, Object> parameters = new HashMap<String , Object>();
		parameters.put("uid", vo.getUid());
		parameters.put("finished", MissionState.FINISHED);
		List<Mission> list = (List<Mission>) baseDAO.exeQuery("from Mission where helper.uid=:uid and state=:finished", parameters);
		return list;
	}

	@Override
	public List<Mission> listBeHelp(MissionVO vo) {
		Map<String, Object> parameters = new HashMap<String , Object>();
		parameters.put("uid", vo.getUid());
		parameters.put("finished", MissionState.FINISHED);
		List<Mission> list = (List<Mission>) baseDAO.exeQuery("from Mission where owner.uid=:uid and state=:finished", parameters);
		return list;

	}

	public BaseDAO getBaseDAO() {
		return baseDAO;
	}

	public void setBaseDAO(BaseDAO baseDAO) {
		this.baseDAO = baseDAO;
	}

	public NoticeSender getSender() {
		return sender;
	}

	public void setSender(NoticeSender sender) {
		this.sender = sender;
	}



	public MessageService getMessageService() {
		return messageService;
	}



	public void setMessageService(MessageService messageService) {
		this.messageService = messageService;
	}

	
	
	
}
